package com.ht.web_vr_home_tour_backend.utils;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTException;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.signers.JWTSignerUtil;
import com.ht.web_vr_home_tour_backend.obj.dto.UserInfoDto;

import java.util.HashMap;
import java.util.Map;

public class TokenUtil {
    // todo 这个需要换掉，不能写死
    public static byte[] tokenSignerData = "aldsfoizcuvojroqejlgcjzbojasf".getBytes();

    // 用户token payload中存放用户数据对象的key
    public static String tokenUserKeyName = "user";

    // 不要实例一个签名器然后导出扔
    // 这种用法，会在高并发的场景下导致jwt验证失败
    // public static JWTSigner signer;
    // todo 写个单元测试，测一测，然后写个博客
    // static {
    //     signer = JWTSignerUtil.hs256(tokenSignerData);
    // }

    /**
     * 通过用户数据创建token
     * @param user 用户传输对象
     * @return token字符串
     */
    public static String createToken(UserInfoDto user) {
        JWT jwt = new JWT();
        Map<String, Object> payloads = new HashMap<>();
        payloads.put(tokenUserKeyName, user);
        jwt.addPayloads(payloads);
        jwt.setExpiresAt(DateTime.now().offset(DateField.DAY_OF_YEAR, 7));
        return jwt.sign(JWTSignerUtil.hs256(tokenSignerData));
    }

    /**
     * 验证token，并返回用户
     * @param token token字符串
     * @return token对应的用户，验证失败返回空
     */
    public static UserInfoDto getUser(String token) {
        try {
            JWT jwt = JWTUtil.parseToken(token);
            jwt.setSigner(JWTSignerUtil.hs256(tokenSignerData));
            if (!jwt.validate(0)) {
                return null;
            }
            return jwt.getPayloads().getBean(tokenUserKeyName, UserInfoDto.class);
        } catch (JWTException e) {
            return null;
        }
    }
}
